package com.framework.simplemvc.config;

import cn.dev33.satoken.exception.DisableLoginException;
import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;
import com.framework.common.api.CommonResult;
import com.framework.common.exception.ApiException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 全局异常处理
 */
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler {

    @ResponseBody
    @ExceptionHandler(value = ApiException.class)
    public CommonResult handle(ApiException e) {
        e.printStackTrace();
        if (e.getErrorCode() != null) {
            return CommonResult.failed(e.getErrorCode());
        }
        return CommonResult.failed(e.getMessage());
    }

    @ResponseBody
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public CommonResult handleValidException(MethodArgumentNotValidException e) {
        e.printStackTrace();
        BindingResult bindingResult = e.getBindingResult();
        String message = null;
        if (bindingResult.hasErrors()) {
            FieldError fieldError = bindingResult.getFieldError();
            if (fieldError != null) {
//                message = fieldError.getField() + ":" + fieldError.getDefaultMessage();
                message = fieldError.getDefaultMessage();
            }
        }
        return CommonResult.failed(message);
    }

    @ResponseBody
    @ExceptionHandler(value = BindException.class)
    public CommonResult handleValidException(BindException e) {
        e.printStackTrace();
        BindingResult bindingResult = e.getBindingResult();
        String message = null;
        if (bindingResult.hasErrors()) {
            FieldError fieldError = bindingResult.getFieldError();
            if (fieldError != null) {
                // fieldError.getField() +
                message = fieldError.getDefaultMessage();
            }
        }
        return CommonResult.failed(message);
    }

    // 全局异常拦截（拦截项目中的NotLoginException异常）
    @ResponseBody
    @ExceptionHandler(value = {NotLoginException.class, NotRoleException.class, NotPermissionException.class, DisableLoginException.class})
    public CommonResult handlerNotLoginException(Exception e) {
        e.printStackTrace();
        // 不同异常返回不同状态码
        if (e instanceof NotLoginException) {
            // 如果是未登录异常
            NotLoginException ee = (NotLoginException) e;
            return CommonResult.unauthorized(ee.getMessage());
        } else if (e instanceof NotRoleException) {
            // 如果是角色异常
            NotRoleException ee = (NotRoleException) e;
            return CommonResult.failed("无此角色：" + ee.getRole());
        } else if (e instanceof NotPermissionException) {
            // 如果是权限异常
            NotPermissionException ee = (NotPermissionException) e;
            return CommonResult.failed("无此权限：" + ee.getCode());
        } else if (e instanceof DisableLoginException) {
            // 如果是被封禁异常
            DisableLoginException ee = (DisableLoginException) e;
            return CommonResult.failed("账号被封禁：" + ee.getDisableTime() + "秒后解封");
        } else {
            // 普通异常, 输出：500 + 异常信息
            return CommonResult.failed(e.getMessage());
        }
    }

    // 全局异常拦截（拦截项目中的所有异常）
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public CommonResult<?> handlerException(Exception e) throws Exception {
        e.printStackTrace();
        log.error("Exception 异常：" + e.getMessage(), e);
        return CommonResult.failed(e.getMessage());
    }
}
